﻿package game.alternativa.ModelViewer {
	import alternativa.engine3d.core.Camera3D;
	import alternativa.engine3d.core.Object3D;
	import alternativa.engine3d.core.Debug;
	
	import flash.display.Stage;
	import flash.events.MouseEvent;
	import flash.display.MovieClip;
	import flash.display.Stage3D;
	import alternativa.engine3d.core.View;
	
	public class ModelCamera extends Object3D {
		
		public static const PERSPECTIVE_PROJECTION : String = "perspective";
		public static const ORTHOGONAL_PROJECTION : String = "orthogonal";
		private var stage : Stage;
		private var tempX : Number;
		private var tempY : Number;
		private var tempRZ : Number;
		private var tempRX : Number;
		private var camera : Camera3D;
		private var _projection : String = PERSPECTIVE_PROJECTION;
		
		public var isDown:Boolean = false;
	 
		public function ModelCamera(vp:MovieClip, view:View, params:IModelParams) {
			this.camera = new Camera3D(params.camera.nearClipping, params.camera.farClipping);
			stage = vp.stage;
			addChild(camera);
			for (var iCamera:String in params.camera) {
				camera[iCamera] = params.camera[iCamera];
			}
			camera.view = view;
			
			if (params.isDebugger) {
				camera.debug = true;
				camera.addToDebug ( Debug.BOUNDS, Object3D );
			}
			
			rotationX = -0.529976651502621;
			rotationY = 0;
			rotationZ = 1.1548630468789403;
			vp.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
			stage.addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheel);
			
		}
	 	
		public function render(stage3D:Stage3D) {
			camera.render(stage3D);
		}
		
		private function onMouseDown(event : MouseEvent): void {
			isDown = true;
			tempX = stage.mouseX;
			tempY = stage.mouseY;
			tempRX = rotationX;
			tempRZ = rotationZ;
			stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
			stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
		}
	 
		private function onMouseMove(event : MouseEvent) : void {
			var factor : Number = 200;
			var newRz : Number = tempRZ + (tempX - stage.mouseX) / factor;
			var newRx : Number = tempRX + (tempY - stage.mouseY) / factor;
			rotationX = newRx;
			rotationZ = newRz;
		}
	 
		private function onMouseUp(event : MouseEvent) : void {
			isDown = false;
			tempX = stage.mouseX;
			tempY = stage.mouseY;
			stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
		}
	 
		private function onMouseWheel(event : MouseEvent) : void {
			var forceShift : Number = 1;
			if (event.shiftKey) {
				forceShift = 5;
			}
			var newCameraY:Number = camera.y + event.delta * forceShift;
			if (newCameraY > -5) newCameraY = -5;
			if (newCameraY < -1350) newCameraY = -1350;
			camera.y = newCameraY;
		}
	 
		public function get projection() : String {
			return _projection;
		}
	 
		public function set projection(value : String) : void {
			if (_projection != value) {
				_projection = value;
				if (_projection == PERSPECTIVE_PROJECTION) {
					camera.orthographic = false;
				} else {
					camera.orthographic = true;
				}
			}
		}
	}
}